package praktikumid.w10.p5;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 * Draw panel, where we draw our shapes.
 * @author Ago
 *
 */
public class DrawPanel extends JPanel {
	
	/**
	 * List of all the shapes.
	 */
	private List<Shape> shapes = new ArrayList<Shape>();
	
	/**
	 * Reference to the active shape,
	 * which can be moved and is highlighted.
	 */
	private Shape activeShape;
	
	class DrawListener extends MouseAdapter implements KeyListener {
		@Override
		public void mouseDragged(MouseEvent e) {
			if (SwingUtilities.isRightMouseButton(e)) {
				// SwingUtilities has some helper methods,
				// here we use the method to detect,
				// whether right button is clicked.
				
				// select the closest shape
				selectClosestShape(e.getPoint());
			} else {
				// if not right button, delegate drag
				getLastShape().mouseDragged(e);
			}
			repaint();
		}
		/*
		@Override
		public void mouseClicked(MouseEvent e) {
			// PRESSED
			// RELEASED
			// CLICK
			//
			getLastShape().mouseClicked(e);
			repaint();
		}
		*/
		
		@Override
		public void mouseReleased(MouseEvent e) {
			if (SwingUtilities.isLeftMouseButton(e)) {
				// let's only delegate mouseRelease
				// if left button is clicked.
				
				// One way would be to do all this
				// left/right check in the shape.
				// That way every shape can decide
				// what to do with different buttons.
				getLastShape().mouseReleased(e);
			}
		}
		@Override
		public void mousePressed(MouseEvent e) {
			if (SwingUtilities.isLeftMouseButton(e)) {
				getLastShape().mousePressed(e);
				repaint();
			}
		}

		@Override
		public void keyPressed(KeyEvent e) {
			//System.out.println(e);
			if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				// right arrow is clicked
				if (activeShape != null) {
					// if we have active shape,
					// let's move it to the right
					activeShape.move(10, 0);
					repaint();
				}
			}
			
		}

		@Override
		public void keyReleased(KeyEvent e) {
			// we need to implement this here because
			// we implement KeyListener interface
			
		}

		@Override
		public void keyTyped(KeyEvent e) {
			
		}
	}
	
	/**
	 * Constructor, let's set up the panel.
	 */
	public DrawPanel() {
		setBackground(Color.WHITE);
		
		//shapes.add(new Rectangle());
		
		// we use the same instance of
		// the listener for different type
		// of event listeners.
		DrawListener l = new DrawListener();
		addMouseListener(l);
		addMouseMotionListener(l);
		addKeyListener(l);
		
		// By default, JPanel is not focused.
		// In order to listen key events (key pressed etc)
		// we need to get focus. Therefore, we first
		// need to make panel focusable.
		setFocusable(true);
		// after that, we need to request focus for
		// the panel.
		requestFocus();
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		for (Shape s : shapes) {
			// let's call paint method for every shape
			s.paint(g);
		}
	}
	
	/**
	 * Returns the last shape. If the list of shapes
	 * is empty or the last shape is finished,
	 * we create a new shape, add it to the list and
	 * return it.
	 * @return The last shape, which we are still drawing
	 */
	public Shape getLastShape() {
		if (shapes.size() == 0 ||
				shapes.get(shapes.size() - 1).isFinished()) {
			// if we don't have any shapes OR
			// last shape is finished, let's create a new one
			//Shape s = new Rectangle();
			Shape s = new Polygon();
			shapes.add(s);
		}
		return shapes.get(shapes.size() - 1);
	}
	
	/**
	 * Selects the closest shape to the specified point.
	 * @param p Point, which is used to find the closest shape.
	 */
	public void selectClosestShape(Point p) {
		int minDistance = Integer.MAX_VALUE;
		Shape closestShape = null;
		for (Shape s : shapes) {
			// let's find the distance from p to every shape
			int d = s.getDistance(p);
			if (d < minDistance) {
				// let's store the closest distance and shape
				minDistance = d;
				closestShape = s;
			}
		}
		activeShape = closestShape;
		for (Shape s : shapes) {
			// let's color the shapes
			if (s == closestShape) {
				// here we just set it active ..
				s.setActive(true);
			} else {
				// or not-active
				s.setActive(false);
			}
		}
		
	}
}
